<?php

namespace Huang\PhpPersonalTools;

use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

class Execl
{
    /**
     * 读取 Excel 文件指定行数开始的数据
     * @param string $filePath Excel 文件路径
     * @param int $startRow 开始读取的行号（例如：2 表示从第二行开始）
     * @return array 读取的数据数组 （过滤了空行）
     */
    public static function readExeclData($filePath, $startRow = 2)
    {
        // 验证文件是否存在
        if (!file_exists($filePath)) {
            throw new \Exception('文件不存在');
        }
        /** @var Xlsx $objRead */
        $reader = IOFactory::createReader('Xlsx');
        if (!$reader->canRead($filePath)) {
            /** @var Xls $objRead */
            $reader = IOFactory::createReader('Xls');

            if (!$reader->canRead($filePath)) {
                throw new \Exception('只支持导入Excel文件！');
            }
        }
       // $reader = IOFactory::createReader('Xlsx');
        $reader->setReadDataOnly(TRUE);
        $spreadsheet = $reader->load($filePath); //载入excel表格
        // 获取活动工作表
        $worksheet = $spreadsheet->getActiveSheet();

        // 遍历工作表中的行和列，去除空行
        $rows = [];
        $rowIterator = $worksheet->getRowIterator($startRow);
        foreach ($rowIterator as $rowIndex => $row) {
            $cellIterator = $row->getCellIterator();
            $cellIterator->setIterateOnlyExistingCells(false); // 遍历所有单元格，包括空单元格
            $rowData = [];
            foreach ($cellIterator as $cell) {
                $rowData[] = $cell->getValue();
            }
            if (!empty(array_filter($rowData))) {
                $rows[$rowIndex] = $rowData;
            }
        }

        return $rows;
    }

    /**
     * 导出Excel文件
     * @param array $headers 导出列的标题
     * @param array $data 导出的具体数据，二维数组
     * @param string $filename 导出的文件名 不要扩展名 ，例如： 测试
     * @param string $filePath 导出的文件路径   \think\facade\Env::get('root_path') . "public/uploads/execl/".date("Y-m-d");
     * @param array $columnWidths $columnWidths = ['A' => 20, 'B' => 30];
     */
    public static function export($headers, $data, $filePath, $filename, $ajaxExport = false, $columnWidths = [])
    {
        // 创建一个新的Excel对象
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        $columnIndex=1;
        $rowIndex=0;
        // 设置标题行
        $rowIndex = 1;
        $keyC = ord("A");
        foreach ($headers as $header) {
            $colKey = chr($keyC);
            $sheet->setCellValue($colKey."1",$header);
            self::setCellColor($spreadsheet,$colKey . '1', 'FFDDEAF3');
            // 设置列宽
            if (isset($columnWidths[$colKey])) {
                $sheet->getColumnDimension($colKey)->setWidth($columnWidths[$colKey]);
            }
            $keyC++;
        }
        $rowIndex++; // 移动到下一行以开始填充数据
        // 填充数据
        foreach ($data as $row) {
            $columnIndex = 1;
            foreach ($row as $value) {
                $sheet->setCellValueByColumnAndRow($columnIndex, $rowIndex, $value);
                $columnIndex++;
            }
            $rowIndex++;
        }
        // 设置导出文件名
        $fileNameWithExtension = $filename . '.xlsx';
        $writer = new Xlsx($spreadsheet);

        if ($ajaxExport) {
            //这里的filepath是 类似tp5 框架的
            if (!file_exists($filePath)) {
                mkdir($filePath, 0777, true);
            }
            $savePath = $filePath ."/". $fileNameWithExtension;
            $writer->save($savePath);
            return $savePath;
        } else {//直接输出浏览器
            // 直接输出到浏览器进行下载
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            header('Content-Disposition: attachment;filename="' . $fileNameWithExtension . '"');
            header('Cache-Control: max-age=0');
            $writer->save('php://output');
            exit; // 确保后面没有其他输出影响文件下载
        }
    }
    /**
     * 设置单元格颜色
     *
     * @param
     * @param string|array $cellRef 单元格引用，可以是单个单元格如"A1"，也可以是单元格范围如"A1:B10"
     * @param string $colorType 颜色类型，'bg'为背景色，'font'为字体色
     * @param string $colorHex 颜色的十六进制值，如"#FF0000"为红色
     */
    public static function setCellColor(Spreadsheet $spreadsheet, $cellRef,  $colorHex='#FF0000')
    {
        $spreadsheet->getActiveSheet()->getStyle($cellRef)->getFont()->getColor()->setARGB($colorHex);
    }


    public static function csvexport($fileName = '', $headerList = array(), $data = array())
    {
        ob_clean();
        //文件名称转码
        $fileName = iconv('UTF-8', 'GBK', $fileName);
//设置header头
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename=' . $fileName . '.csv');
        header('Cache-Control: max-age=0');
//打开PHP文件句柄,php://output,表示直接输出到浏览器
        $fp = fopen("php://output", "a");

//输出Excel列表名称信息
        foreach ($headerList as $key => $value) {
            $headerList[$key] = iconv('UTF-8', 'GBK', $value);//CSV的EXCEL支持BGK编码，一定要转换，否则乱码
        }
//使用fputcsv将数据写入文件句柄
        fputcsv($fp, $headerList);
        mb_convert_variables('GBK', 'UTF-8', $header);
//计数器
        $num = 0;
//每隔$limit行，刷新一下输出buffer,不要太大亦不要太小
        $limit = 100000;
//逐行去除数据,不浪费内存
        $count = count($data);
        for ($i = 0; $i < $count; $i++) {
            $num++;
            //刷新一下输出buffer，防止由于数据过多造成问题
            if ($limit == $num) {
                ob_flush();
                flush();
                $num = 0;
            }
            $row = $data[$i];
            foreach ($row as $key => $value) {
                $row[$key] = iconv('UTF-8', 'GBK', $value);
            }
            fputcsv($fp, $row);

        }
        //关闭句柄
        fclose($fp);
        die;
    }
}
